package com.yuyou.tas.admin.service.impl;

import com.yuyou.tas.admin.service.*;
import com.yuyou.tas.admin.vo.req.ReqLogin;
import com.yuyou.tas.admin.vo.req.ReqPassWordReset;
import com.yuyou.tas.admin.vo.req.ReqPassWordUpdate;
import com.yuyou.tas.admin.vo.resp.RespAuthResource;
import com.yuyou.tas.admin.vo.resp.RespLogin;
import com.yuyou.tas.service.api.admin.entity.*;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.ResBoolSimpleInfo;
import com.yuyou.tas.util.config.SystemConfig;
import com.yuyou.tas.util.enums.admin.AuthRoleEnums;
import com.yuyou.tas.util.enums.admin.AuthUserEnums;
import com.yuyou.tas.util.message.admin.LoginMess;
import com.yuyou.tas.util.tool.BeanUtils;
import com.yuyou.tas.util.tool.DateUtil;
import com.yuyou.tas.util.tool.DefindBeanUtils;
import com.yuyou.tas.util.tool.TokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class LoginServiceImpl implements ILoginService{

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	private ICaptchaService captchaService;
	
	@Autowired
	private IAuthUserService authUserService;
	
	@Autowired
	private IAuthRoleService authRoleService;

	@Autowired
	private IAuthResourceService authResourceService;
	@Autowired
	private IAuthUserSubjectService authUserSubjectService;
	@Autowired
	private IAuthUserSectionService authUserSectionService;
	
	@Autowired
	private IAuthOrganService authOrganService;

	@Autowired
	private IAuthOrganizationSubSecService authOrganizationSubSecService;
	
	@Override
	public ResBoolSimpleInfo<RespLogin> login(ReqLogin reqLogin) {
		ResBoolSimpleInfo<RespLogin> res=new ResBoolSimpleInfo<RespLogin>();
		RespLogin respLogin=new RespLogin();
			
			if(reqLogin.getAuthOrganizationId()==null){
				List<AuthOrganizationExt> activeOrganList=authOrganService.findActiveOrganByAcc(reqLogin.getPhone());
				if(activeOrganList.size()==1){
					reqLogin.setAuthOrganizationId(activeOrganList.get(0).getId());
				}else if(activeOrganList.size()>1){
					res.setSuccess(false);
					res.setMessage(LoginMess.ERR_ORGAN_EMPTY);
					return res;
				}else{
					List<AuthOrganizationExt> organList=authOrganService.findOrganByAcc(reqLogin.getPhone());
					if(organList.size()==1){
						reqLogin.setAuthOrganizationId(organList.get(0).getId());
					}else if(organList.size()>1){
						res.setSuccess(false);
						res.setMessage(LoginMess.ERR_OTHER);
						return res;
					}else{
						res.setSuccess(false);
						res.setMessage(LoginMess.ERR_UPDATE_PASSWORD);
						return res;
					}
				}
			}
		
			AuthUser authUser=authUserService.seleteUserByAcc7Organ(reqLogin.getPhone(),reqLogin.getAuthOrganizationId());
			if(authUser==null){
				res.setSuccess(false);
				res.setMessage(LoginMess.ERR_UPDATE_PASSWORD);
				return res;
			}
						
			if(authUser.getStatus().equals(0)){
				res.setSuccess(false);
				res.setMessage(LoginMess.ERR_STATUS_FREEZE);
				return res;
			}
			
			//验证码
			ResBoolSimpleInfo<String> ver=verifyCode(reqLogin);
			if(!ver.isSuccess()){
				res.setSuccess(false);
				res.setMessage(ver.getMessage());
				return res;
			}
			//密码		
			if(reqLogin.getPassword().equalsIgnoreCase(authUser.getPassword())){
				
				//判断机构账号有效期
				ResBoolSimpleInfo<String> verOrganAcc=authOrganService.validateOrganAcc(authUser.getAuthOrganizationId());
				if(!verOrganAcc.isSuccess()){
					res.setSuccess(false);
					res.setMessage(verOrganAcc.getMessage());
					return res;
				}
				
				if(authUser.getWorkStatus()!=null &&(!authUser.getWorkStatus().equals(AuthUserEnums.workStatus.work.getValue()))){
					res.setSuccess(false);
					res.setMessage(LoginMess.ERR_OTHER);
					return res;
				}
				
				
				
				
				//生成token
		        String token = TokenUtil.GenerateToken();     
		        
		        List<AuthRole>roleList=authRoleService.findAuthRoleByUserId(authUser.getId());	
		        if(roleList.size()==0){
					res.setSuccess(false);
					res.setMessage(LoginMess.ERR_ROLE_EMPTY);
					return res;
		        }
		        Long countC=roleList.stream().filter(authRole -> authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.system.getValue()).count();
		        Long organO=roleList.stream().filter(authRole -> authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.organ.getValue()).count();
		        Long countP=roleList.stream().filter(authRole -> authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.per.getValue()).count();
		        Integer roleType=
		        		countC>0?AuthRoleEnums.roleType.system.getValue():(
		        		organO>0?AuthRoleEnums.roleType.organ.getValue():(
		        		countP>0?AuthRoleEnums.roleType.per.getValue():AuthRoleEnums.roleType.other.getValue()));
		        
		        
		        Long manaCount=roleList.stream().filter(authRole -> 
		        		  authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.system.getValue()
		        		||authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.organ.getValue()
		        		||authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.per.getValue()).count();		        
		        
		        //找出用户资源权限
		        List<RespAuthResource> resList=authResourceService.findAuthResourceByUserId(authUser.getId());
		        
		        Set<String> pageUrlSet=resList.stream().filter(f-> !StringUtils.isEmpty(f.getPageUrl())).map(authResource ->authResource.getPageUrl()).collect(Collectors.toSet());
		        
		        //找出用户科目，年级
		        List<Long> subjectList=authUserSubjectService.findSubjectByAuthUserId(authUser.getId()).stream().map(item->item.getDataSubject()).collect(Collectors.toList());		        
		        Set<Long>sectionSet=authUserSectionService.findUniSectionByUserId(authUser.getId());
		        
		        
		        //非管理员必须要有年级科目属性
//		        if(manaCount==0 && (subjectList.size()==0 || sectionSet.size()==0)){
//					res.setSuccess(false);
//					res.setMessage("年级科目为空");
//					return res;
//		        }
		        
		        //找出机构的科目年级
				List<AuthOrganizationSubSec> ssList = authOrganizationSubSecService.getAllByOrganId(authUser.getAuthOrganizationId());
				Map<Long , List<AuthOrganizationSubSec>> ssMap = BeanUtils.toGroup(ssList , "dataSubject");
				Map<Long , List<Long>> subSecs = new HashMap<>();
				ssMap.forEach((key, value) -> {
					subSecs.put(key , value.stream().map(item -> item.getBaseSectionId()).collect(Collectors.toList()));
				});

		        /*List<AuthOrganizationPermit>permitList=authOrganPermitService.findByOrganId(authUser.getAuthOrganizationId(), null);

		        List<Long> organSubjects=permitList.stream().filter(item ->item.getType().equals(1)).map(item-> item.getfId()).collect(Collectors.toList());
		        List<Long> organSectionIds=permitList.stream().filter(item ->item.getType().equals(2)).map(item-> item.getfId()).collect(Collectors.toList());*/
		        
		        
		        LoginRedisObj obj=new LoginRedisObj(authUser.getId(),authUser.getUsername(),authUser.getAuthOrganizationId(),subSecs,subjectList,sectionSet,countC>0,manaCount>0,roleType,pageUrlSet,authUser.getType());
		        
		        
		        String userIdKey=stringRedisTemplate.opsForValue().get(String.valueOf(authUser.getId()));
		        if(!StringUtils.isEmpty(userIdKey)){
			        stringRedisTemplate.delete(userIdKey);	
		        }
		        stringRedisTemplate.opsForValue().set(token, obj.toJson(), SystemConfig.REDIS_EXPIRE_TIME,SystemConfig.REDIS_EXPIRE_TIME_UNIT);	
		        stringRedisTemplate.opsForValue().set(authUser.getId().toString(), token, SystemConfig.REDIS_EXPIRE_TIME,SystemConfig.REDIS_EXPIRE_TIME_UNIT);		        
		        
		        AuthOrganization authOrganization=authOrganService.selectByPrimaryKey(authUser.getAuthOrganizationId());
		        
		        DefindBeanUtils.copyProperties(obj, respLogin);
		        respLogin.setUserId(authUser.getId());
		        respLogin.setAccessToken(token);
		        respLogin.setSysCode(authOrganization.getSysCode());
		        captchaService.cleanOptStat(reqLogin.getPhone());
		        
		     // 更新最后登录时间
				AuthUser authUserUpdate = new AuthUser();
				authUserUpdate.setId(authUser.getId());
				authUserUpdate.setLoginTime(DateUtil.now());
				authUserService.updateByPrimaryKeySelective(authUserUpdate);
				
				res.setData(respLogin);
				res.setSuccess(true);
		        
			}else{		
				res.setSuccess(false);
				res.setMessage(LoginMess.ERR_UPDATE_PASSWORD);
				captchaService.opsStat(reqLogin.getPhone());
			}
		
		return res;
	}

	

	public ResBoolSimpleInfo<String> verifyCode(ReqLogin reqLogin) {
		ResBoolSimpleInfo<String> res =new ResBoolSimpleInfo<String>();
		boolean need=captchaService.needVerifyCode(reqLogin.getPhone());
		if(need){
			res=captchaService.verifyCode(reqLogin.getToken(), reqLogin.getCaptcha());				
			if(!res.isSuccess()){
				res.setSuccess(false);
				res.setMessage(res.getMessage());
				return res;
			}			
		}
		res.setSuccess(true);
		return res;
	}
	
	@Override
	public ResBoolSimpleInfo<String> updatePass(Long userId,ReqPassWordUpdate reqPassWordUpdate) {	
		ResBoolSimpleInfo<String> res=new ResBoolSimpleInfo<String>();		
		if(!reqPassWordUpdate.getPassword().equals(reqPassWordUpdate.getcPassword())){
			res.setSuccess(false);
			res.setMessage(LoginMess.ERR_2_PASS_NOT_EQUAL);
			return res;
		}	
		AuthUser authUser=authUserService.selectByPrimaryKey(userId);
		if(authUser==null){
			res.setSuccess(false);
			res.setMessage(LoginMess.ERR_UPDATE_PASSWORD);
			return res;
		}		
		if(reqPassWordUpdate.getoPassword().equalsIgnoreCase(authUser.getPassword())){		
			authUser.setPassword(reqPassWordUpdate.getcPassword());
			authUserService.updateByPrimaryKeySelective(authUser);
			res.setSuccess(true);
		}else{
			res.setSuccess(false);
			res.setMessage(LoginMess.ERR_OPASS_NOT_EQUAL);
			return res;
		}
		
		return res;
	}



	@Override
	public ResBoolSimpleInfo<String> resetPass(Long userId,ReqPassWordReset reqPassWordReset) {
		ResBoolSimpleInfo<String> res=new ResBoolSimpleInfo<String>();		
		if(!reqPassWordReset.getPassword().equals(reqPassWordReset.getcPassword())){
			res.setSuccess(false);
			res.setMessage(LoginMess.ERR_2_PASS_NOT_EQUAL);
			return res;
		}	
		AuthUser authUser=authUserService.selectByPrimaryKey(reqPassWordReset.getUserId());
		if(authUser==null){
			res.setSuccess(false);
			res.setMessage(LoginMess.ERR_UPDATE_PASSWORD);
			return res;
		}	
		//操作人
		AuthUser optUser=authUserService.selectByPrimaryKey(userId);
		//操作人是否拥有权限TODO		
		authUser.setPassword(reqPassWordReset.getcPassword());
		authUserService.updateByPrimaryKeySelective(authUser);
		
		return res;
	}
	
	



	

}